﻿// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
// Website: https://admin.blazor.zone

using BlazorAdmin.Extensions;
using BlazorAdmin.Models;
using BlazorAdmin.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BlazorAdmin.Services
{
    /// <summary>
    /// 后台权限管理服务类
    /// </summary>
    public class AdminService : IBootstrapAdminService
    {
        private readonly IUser userService;
        private readonly INavigation navService;
        private readonly ILog loginService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="navigations"></param>
        public AdminService(IUser user, INavigation navigations, ILog login)
        {
            userService = user;
            navService = navigations;
            loginService = login;
        }

        /// <summary>
        /// 通过用户名获取角色集合方法
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public List<string> GetRoles(string userName) => userService.GetRoles(userName);

        /// <summary>
        /// 通过用户名获取授权 App 集合方法
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public List<string> GetApps(string userName) => userService.GetApps(userName);

        /// <summary>
        /// 通过用户名检查当前请求 Url 是否已授权方法
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public Task<bool> AuhorizingNavigation(string userName, string url)
        {
            var ret = navService.GetAllMenus(userName).Any(m => m.Url.Contains(url, StringComparison.OrdinalIgnoreCase));
            return Task.FromResult(ret);
        }

        /// <summary>
        /// 通过用户名检查当前请求 Url 是否已授权方法
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="url"></param>
        /// <param name="blockName"></param>
        /// <returns></returns>
        public bool AuhorizingBlock(string userName, string url, string blockName)
        {
            var ret = userService.GetRoles(userName).Any(i => i.Equals("Administrators", StringComparison.OrdinalIgnoreCase));
            if (!ret)
            {
                var menus = navService.GetAllMenus(userName);
                var menu = menus.FirstOrDefault(m => m.Url.Contains(url, StringComparison.OrdinalIgnoreCase));
                if (menu != null)
                {
                    ret = menus.Any(m => m.ParentID == menu.ID && m.IsResource == SysEnumResource.Block && m.Url.Equals(blockName, StringComparison.OrdinalIgnoreCase));
                }
            }
            return ret;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="userName">登录名</param>
        /// <param name="password">登录密码</param>
        /// <param name="isRemember">是否记住密码</param>
        /// <param name="domain">登录的域</param>
        /// <returns></returns>
        public (JwtUserData, User, string) Login(UserLogin param, bool isRemember, string domain = "")
        {
            var errMsg = string.Empty;
            User user = null;
            JwtUserData userData = null;

            if (string.IsNullOrWhiteSpace(param.UserName))
                errMsg = "登录用户名不能为空";
            if (string.IsNullOrWhiteSpace(param.Password))
                errMsg = "登录用户密码不能为空";
            else
            {
                user = userService.GetUserByUserName(param.UserName);
                if (user == null)
                    errMsg = "您没有登录该系统的权限";
                else if (string.IsNullOrEmpty(domain) && !userService.Authenticate(user, param.Password))
                    errMsg = "用户名或者密码错误";
                else if (!string.IsNullOrEmpty(domain) && !LdapHelper.Login(param.UserName, param.Password, domain))
                    errMsg = "域用户名或者域登录密码不正确";
            }

            if (user != null)
                userData = new() { UserName = param.UserName, IsRemember = isRemember, Domain = domain, JwtTime = DateTime.Now, ExpiredTime = DateTime.Now.AddHours(1) };

            loginService.LoginLog(new()
            {
                UserName = param.UserName,
                IP = param.ClientIP,
                UserAgent = param.UserAgent,
                IsLoginIn = string.IsNullOrEmpty(errMsg)
            });

            return (userData, user, errMsg);
        }
    }
}